/*
 * Dealer.java
 *
 * Copyright(c) 2009 - Kimnach
 * See Main.java for copyright notice.
 *
 */

package initiative;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import player.Player;

/**
 * Initiative dealer. Takes list of players and shuffles for order.
 * Also handles removing and adding of players and keeping track of dead players.
 * @author dkimnach
 */
public class Dealer {

    private Random random = new Random();

    private ArrayList<Player> list;
    private ArrayList<Player> dead;

    private int counter = 0;
    
    
    /**
     * Default constructor, constructs an empty list of players
     */
    public Dealer() {
        list = new ArrayList<Player>();
        dead = new ArrayList<Player>();
    }

    /**
     * Constructs the list of players from array of players passed in
     * @param players ArrayList of players to construct from
     */
    public Dealer(ArrayList<Player> players) {
        list = new ArrayList<Player>(players);
        dead = new ArrayList<Player>();
    }

    /**
     * Shuffles list of players, ignoring all dead players
     * @return shuffled deck
     */
    public ArrayList<Player> deal() {
        for (int i = 0; i < list.size(); i++) {
            Player p = list.get(i);
            if (p.isDead()) {
                list.remove(i);
                dead.add(p);
                i--; // size of list is now less one
            }
        }
        list.trimToSize();

        for (int i = 0; i < 12; i++) {
            Collections.shuffle(list, random);
        }

        list.addAll(dead);
        dead.clear();

        System.out.println("New initiatives dealt");
        counter++;
        return list;
    }

    /**
     * Switches initiatives (positions in list) with two players (numbers are indexes and start at 0)
     * @param thisone first index to swap with second
     * @param thatone second index to swap with first
     */
    public void planB(int thisone, int thatone) {

        if (thisone != thatone) {
            System.out.println(list.get(thisone).getName() + " for " + list.get(thatone).getName());

            Collections.swap(list, thisone, thatone);
        }
    }

    /**
     * Returns current order of players
     * @return current deck
     */
    public ArrayList<Player> getList() {
        System.out.println("Getting list");
        return list;
    }

    /**
     * Move player at [index] to the last index of the list
     * @param index player to move
     * @return index of last position
     */
    public int moveToBottom(int index) {
        int last = list.size() - 1;
        int pos = 0;
        
        do {
            if (pos == 0 && !list.get(last).isDead()) {
                Player p = list.remove(index);
                list.add(p);
                System.out.println("Moving " + p.getName() + " to bottom");
                break;
            } else if (!list.get(last - pos).isDead()) {
                Player p = list.remove(index);
                list.add((last - pos), p);
                System.out.println("Moving " + p.getName() + " to bottom");
                break;
            }
            pos ++;
        }
        while (pos <= last);

        return last - pos;
    }

    /**
     * Move player at [index] to the first index of the list (0)
     * @param index player to move
     * @return index of first position (0)
     */
    public int moveToTop(int index) {
        Player p = list.remove(index);
        list.add(0, p);
        System.out.println("Moving " + p.getName() + " to top");
        return 0;
    }

    /**
     * Kill player at [index] (move to bottom and mark dead)
     * @param index player index to kill
     * @return index of last position
     */
    public int killPlayer(int index) {
        int pos = moveToBottom(index);
        Player p = list.get(pos);
        System.out.println(p.getName() + " dies");
        p.die();
        list.set(pos, p);
        return pos;
    }

    /**
     * Revive a player that was killed (unmark as dead).  Looks up dead player by color rather than name (allows players with same name)
     * @param col color of player that died (if you need to undo it)
     * @return player index that was revived
     */
    public int revive(Color col) {
        int index = -1;
        for (int i = 0; i < list.size(); i++){
            Player p = list.get(i);

            if (p.getColor().equals(col)) {
                System.out.println(p.getName() + " revived");
                p.revive();
                list.set(i, p);
                index = i;
            }
        }
        return index;
    }

    /**
     * Returns current count of deals
     * @return counter
     */
    public int getCounter() {
        return counter;
    }

    public void setCounter(int count) {
        counter = count;
    }

    @Override
    public String toString() {
        String s = "Deck contents: \n";
        for (Player p : list) {
            s += p.getName() + " - " + p.isDead() +"\n";
        }
        s += counter + " deals called\n";
        return s;
    }

    public void removePlayer(Color col) {
        for (int i = 0; i < list.size(); i++){
            Player p = list.get(i);

            if (p.getColor().equals(col)) {
                System.out.println(p.getName() + " removed");
                list.remove(i);
            }
        }
        list.trimToSize();
    }

    public Boolean renamePlayer(Color col, String name) {
        Boolean found = false;
        for (int i = 0; i < list.size(); i++){
            Player p = list.get(i);

            if (p.getColor().equals(col)) {
                System.out.println(p.getName() + " removed");
                p.setName(name);
                list.set(i, p);
                found = true;
            }
        }

        return found;
    }

    public void addPlayer(String name, Color col) {
        list.add(new Player(name, col));
        list.trimToSize();
    }

    public void newGame() {
        list.clear();
        dead.clear();
        counter = 0;
    }
}